#pragma once
#ifndef MATERIAL_PROJECT_HH_
#define MATERIAL_PROJECT_HH_

#include <qtreewidget.h>
#include <qtoolbar.h>
#include <qboxlayout.h>

#include <LitEditorDialog.h>
#include "MaterialPrerequisites.h"
#include "MaterialProjectFile.h"

#include "ui_materialeditor.h"
#include <boost\asio.hpp>

namespace Lit
{
	namespace Editor
	{
		namespace Material
		{
			class ProjectXmlSerialiser;
			class SceneParameters;
			
			class ProjectTools : public QToolBar
			{
				Q_OBJECT

			protected:
				Project * mProject;
				
				QAction *	mAddAction;
				QMenu *		mAddMenu;
				QAction *	mAddFilter;
				QAction *	mAddNew;
				QAction *	mAddExisting;
				QAction *	mRemoveItem;
				QAction *	mItemProperties;
			public:
				ProjectTools( Project * proj = NULL );
				~ProjectTools( );

				void updateUi( Project * project, QTreeWidgetItem * item );
				void execContextMenu( Project * project, QTreeWidgetItem * item, const QPoint& pos = QCursor::pos() );
			};
			class Project : public QWidget
			{
				Q_OBJECT

			protected:
				friend class ProjectXmlSerialiser;

			public:
				static const std::string DEFAULT_RESOURCE_GROUP;

				void prepareResources( );
				void updateResources( );
				
				Project( Ui::MaterialEditorClass* _ui, const QStringList &cmd_args = QStringList() );
				~Project(void);

				std::vector<ProjectFileDefinition> getRecentProjects();
				void saveRecentProjects();
				void loadRecentProjects();

				bool eventFilter(QObject*obj, QEvent*evt); 
				bool isCreated() const;

				void newProject( const std::string &name_ = "", bool autosave = true, bool autocreate = true );
				void openProject( const std::string &filename = "" );
				void saveProject( const std::string &filename = "" );
				bool closeProject();

				FilePath getFilePath( const std::string &name ) const;
				std::string getProjectHome() const;

				Ogre::Log& logMessage( const std::string &msg, bool debug = false );

				bool hasFile( const std::string &name ) const;
				ProjectFilePtr getFile( const std::string &name );
				std::vector<ProjectFilePtr> createFile( );
				ProjectFilePtr createFile( const std::string &name, const std::string &content="" );
				ProjectFilePtr openFile( const std::string &name );
				void removeFile( const ProjectFilePtr &f, bool delete_on_disk_too = false );
				void removeFile( const std::string &name, bool delete_on_disk_too = false );
				void clearFiles();
				
				const std::vector<std::string> & getCommandArguments() const;
				std::vector<std::string> & getCommandArguments();

				void setCommandArguments( const QStringList &args_ );
			
				bool hasModifiedWindow( ) const;
				void saveModifiedWindows( );
			
				QToolBar * getToolBar();
				const QToolBar * getToolBar() const;

				QTreeWidget * getTreeWidget();
				const QTreeWidget * getTreeWidget() const;

				void setupUi( const std::string &name );
				void updateUi();
				
				const ProjectFilePtr& getFileFromTree( const QTreeWidgetItem * item ) const;
				const ProjectFilePtr& getFileFromWidget( const EditorWidget * item ) const;
				const ProjectFilePtr& getFileFromWindow( const Window * item ) const;

				bool isFilter( const std::string &name ) const;
				bool isFile( const std::string &name ) const;
		
				void createScene();
				void destroyScene();
				
				void compile(const std::string &name);
				void compileProject();

				std::string getName() const;

				QTreeWidgetItem * getRootNode();
				const QTreeWidgetItem * getRootNode() const;

				QMdiArea* getMdiArea();
				const QMdiArea* getMdiArea() const;
			
				bool isSavePathDefined() const;
				const std::string &getSavePath() const;

				const RefPtr<Ogre::Entity>& getEntity() const;
				const RefPtr<Ogre::Light>& getLight() const;
				
				void fitMeshInViewport();

				void setSceneParameters( RefPtr<SceneParameters> params );
				const RefPtr<SceneParameters>& getSceneParameters( ) const;

				void setMesh( const std::string &meshName, const Lit::Vec3& scale = Vec3::UNIT_SCALE );
				void setMaterial( const std::string &name );
				void setMaterial( Ogre::MaterialPtr mat );

			protected:
				std::unordered_map<std::string, ProjectFile*>	mFiles;
				RefPtr<SceneParameters>							mParameters;

				RefPtr<Ogre::SceneManager>						mScene;
				RefPtr<Ogre::Camera>							mCamera;

				std::string						mSavePath;
				bool							mCreated;
				QVBoxLayout *					mLayout;
				ProjectTools*					mTools;
				QTreeWidget *					mTree;
				QTreeWidgetItem *				mRoot;		
				RefPtr<ProjectXmlSerialiser>	mSerialiser;	
				std::vector<std::string>		mArgs;

				Ui::MaterialEditorClass* ui;

			protected slots:
				void on_createShader_triggered( );
				void on_actionAddExistingItem_triggered();
				void on_actionAddNewItem_triggered();
				void on_actionAddFilter_triggered();
				void on_actionRemoveItem_triggered();
				void on_actionItemProperties_triggered();


				void treeItemDoubleClicked( QTreeWidgetItem * item, int );
				void treeItemClicked( QTreeWidgetItem* itm, int col );
			};
			
		};
	};
};
#endif